/*
 *
 *
 */
#include "gkt_board.h"
#include "gkt_user.h"
#include "window_common.h"
#include "window_verify.h"

#define WINDOW_OPCODE_F_INITIALIZED	(1U << 0)
#define WINDOW_OPCODE_F_NEED_LOGIN	(1U << 1)
#define WINDOW_OPCODE_F_SHOW_WINDOW	(1U << 2)

typedef struct _window_opcode_compatible_item {
	uint32_t	old_value;
	uint32_t	new_value;
} window_opcode_compatible_item_s;
#define WINDOW_OPCODE_COMPATIBLE_ITEM(_name)	\
	{	\
		.old_value	= WINDOW_OPCODE_COMPATIBLE_##_name,	\
		.new_value	= WINDOW_OPCODE_####_name,	\
	}
static const window_opcode_compatible_item_s sc_window_opcode_compatible_items[] = {
	WINDOW_OPCODE_COMPATIBLE_ITEM(SYSTEM_INFO),
	WINDOW_OPCODE_COMPATIBLE_ITEM(FACTORY_TEST_NBC),
	WINDOW_OPCODE_COMPATIBLE_ITEM(FACTORY_TEST_BC),
	WINDOW_OPCODE_COMPATIBLE_ITEM(AGING_TEST)
};
static const uint32_t sc_window_opcode_compatible_items_num = 
	sizeof(sc_window_opcode_compatible_items) / sizeof(window_opcode_compatible_item_s);

typedef struct _window_opcode_item {
	uint32_t	value;
	gkt_window_id_t	window_id;
	uint16_t	flags;
	uint32_t	data;
	window_opcode_action_fn	action;
} window_opcode_item_s;

#define WINDOW_OPCODE_ITEM(_name, _window_name, _flags, _data)	\
	{	\
		.value	= WINDOW_OPCODE_##_name,	\
		.window_id	= WINDOW_ID_##_window_name,	\
		.flags	= _flags,	\
		.data	= _data	\
	}

static const window_opcode_item_s sc_window_opcode_items[] = {
	WINDOW_OPCODE_ITEM(SYSTEM_INFO, sysinfo, WINDOW_OPCODE_F_SHOW_WINDOW, 0),
};
static const uint32_t sc_window_opcode_items_num = 
	sizeof(sc_window_opcode_items) / sizeof(window_opcode_item_s);

typedef struct _window_opcode_data {
	const window_opcode_item_s	*item;
	window_verify_attr_u	verify_attr;
} window_opcode_data_s;
static window_opcode_data_s s_window_opcode_data;

void window_opcode_put(uint32_t opcode, uint32_t data)
{
	gkt_window_s *window;

	window = gkt_window_find(GKT_WINDOW_ID_START);
	if (window) {

	}
}

void window_opcode_handler(uint32_t opcode)
{
	const window_opcode_compatible_item_s *c_cpt_item;
	const window_opcode_item_s *c_item;
	gkt_user_amount_s amount;
	uint32_t new_opcode;
	uint32_t i;
	int retval;

	gkt_info("opcode: (%d) value = %u\n", 
		g_window_ram_data.opcode_state, opcode);

	if (WINDOW_OPCODE_ST_IDLE == g_window_ram_data.opcode_state) {
		new_opcode = opcode;
		for (i = 0; i < sc_window_opcode_compatible_items_num; i++) {
			c_cpt_item = &sc_window_opcode_compatible_items[i];
			if (c_cpt_item->old_value == opcode) {
				new_opcode = c_cpt_item->new_value;
				gkt_info("opcode: <compatible> %u --> %u\n", opcode, new_opcode);
				break;
			}
		}

		for (i = 0; i < sc_window_opcode_items_num; i++) {
			c_item = &sc_window_opcode_items[i];
			if (c_item->value = new_opcode) {
				if (c_item->flags & WINDOW_OPCODE_F_INITIALIZED) {
					amount.used_nums = 0;
					retval = gkt_user_get_amount(&amount, GKT_USER_AUTH_ADMIN, 
									GKT_USER_TYPE_MAX);
					if ((GKT_SUCCESS == retval) && !amount.used_nums) {
						gkt_info("opcode: not initialized!\n");
						return;
					}
				}
			
				if (c_item->flags & WINDOW_OPCODE_F_NEED_LOGIN) {
					g_window_ram_data.opcode_state = WINDOW_OPCODE_ST_LOGGING;

					s_window_opcode_data.verify_attr.type = WINDOW_VERIFY_TYPE_LOGIN;
					s_window_opcode_data.verify_attr.login.action = WINDOW_VERIFY_LOGIN_ACTION_USER_DEFINED;
					s_window_opcode_data.verify_attr.login.user_id = 0;
					gkt_window_show(WINDOW_ID_verify, (uint32_t)&s_window_opcode_data.verify_attr);
				}
				else
					gkt_window_show(c_item->window_id, c_item->data);

				break;
			}
		}
	}
	else if (WINDOW_OPCODE_ST_LOGGING == g_window_ram_data.opcode_state) {
		if (WINDOW_OPCODE_CURRENT == opcode) {
			c_item = s_window_opcode_data.item;
			if (s_window_opcode_data.verify_attr.login.user_id)
				gkt_window_show(c_item->window_id, c_item->data);
			g_window_ram_data.opcode_state = WINDOW_OPCODE_ST_IDLE;
		}
		else {
			gkt_error("opcode: previous opcode(%u) not finish!\n", 
					s_window_opcode_data.item->value);
		}
	}
	else {
		
	}
}

